﻿// -----------------------------------------------------------------------
// <copyright file="PluralRulesFactory.cs" company="Moveax, LLC">
// Copyright (c) 2013 Andrey Veselov. All rights reserved.
// License:  Microsoft Public License (MS-PL)
// Contacts: http://andrey.moveax.com andrey@moveax.com
// </copyright>
// -----------------------------------------------------------------------

namespace Moveax.Pluralization.Core
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using Moveax.Pluralization.Core.LanguageRules;

    /// <summary>Provides access to factory method for creating plural rules. </summary>
    public class PluralRulesFactory
    {
        private static readonly IDictionary<string[], Func<string, IPluralRules>> _ruleConstrtuctors
            = new Dictionary<string[], Func<string, IPluralRules>>() {
                { new string[] { "en", "de", "it", "es", "pt" }, lang => new CommonPluralRules(lang) },
                { new string[] { "fr" }, lang => new FrenchPluralRules() },
                { new string[] { "ru", "uk", "be" }, lang => new SlavicPluralRules(lang) }
            };

        private static readonly Func<string, IPluralRules> _defaultRuleConstrtuctor;

        /// <summary>Initializes the <see cref="PluralRulesFactory"/> class.</summary>
        static PluralRulesFactory()
        {
            PluralRulesFactory._defaultRuleConstrtuctor = PluralRulesFactory._ruleConstrtuctors
                .First(c => c.Key.Contains("en"))
                .Value;
        }

        /// <summary>Creates the plural rules instance with specified culture.</summary>
        /// <param name="cultureInfo">The culture.</param>
        /// <returns>The <see cref="IPluralRules"/> object that represents plural rules for the specified culture.</returns>
        /// <exception cref="System.ArgumentNullException">cultureInfo</exception>
        public IPluralRules Create(CultureInfo cultureInfo)
        {
            if (cultureInfo == null)
                throw new ArgumentNullException("cultureInfo");

            string cultureName = cultureInfo.Name.Substring(0, 2).ToLower();

            Func<string, IPluralRules> ruleConstrtuctor = PluralRulesFactory._ruleConstrtuctors
                .FirstOrDefault(k => k.Key.Contains(cultureName))
                .Value;

            return ruleConstrtuctor != null ?
                ruleConstrtuctor(cultureName) :
                PluralRulesFactory._defaultRuleConstrtuctor(cultureName);
        }
    }
}
